/*
 * Copyright (c) 2009. Silenus Consultoria, S.L.
 */
package es.silenus.detecta.model;

import org.springframework.security.GrantedAuthority;


/**
 * Granted authority based on Role.
 *
 * @author <a href="mailto:malonso@silenus-consultoria.es">Mariano Alonso</a>
 *
 * @since 15-jun-2009 11:05:50
 */
public class RoleGrantedAuthority implements GrantedAuthority {
	/**
	 * The role.
	 */
	private Role role;

/**
   * Constructor.
   *
   * @param role the role.
   */
	public RoleGrantedAuthority(final Role role) {
		this.role = role;
	}

/**
   * Constructor.
   */
	public RoleGrantedAuthority() {
		this.role = Role.ROLE_ANONYMOUS;
	}

	/**
	 * Sets the role.
	 *
	 * @param role the role.
	 */
	public void setRole(final Role role) {
		this.role = role;
	}

	/**
	 * If the <code>GrantedAuthority</code> can be represented as a <code>String</code> and that
	 * <code>String</code> is sufficient in precision to be relied upon for an access control decision by an {@link
	 * org.springframework.security.AccessDecisionManager} (or delegate), this method should return such a
	 * <code>String</code>.<p>If the <code>GrantedAuthority</code> cannot be expressed with sufficient precision as
	 * a <code>String</code>, <code>null</code> should be returned. Returning <code>null</code> will require an
	 * <code>AccessDecisionManager</code> (or delegate) to  specifically support the <code>GrantedAuthority</code>
	 * implementation,  so returning <code>null</code> should be avoided unless actually  required.</p>
	 *
	 * @return a representation of the granted authority (or <code>null</code> if the granted authority cannot be
	 * 				 expressed as a <code>String</code> with sufficient precision).
	 */
	public String getAuthority() {
		return role.name();
	}

	/**
	 * Compares this object with the specified object for order.  Returns a negative integer, zero, or a positive
	 * integer as this object is less than, equal to, or greater than the specified object. The implementor must ensure
	 * <tt>sgn(x.compareTo(y)) == -sgn(y.compareTo(x))</tt> for all <tt>x</tt> and <tt>y</tt>.  (This implies that
	 * <tt>x.compareTo(y)</tt> must throw an exception iff <tt>y.compareTo(x)</tt> throws an exception.) The implementor
	 * must also ensure that the relation is transitive: <tt>(x.compareTo(y)&gt;0 &amp;&amp; y.compareTo(z)&gt;0)</tt>
	 * implies <tt>x.compareTo(z)&gt;0</tt>. Finally, the implementor must ensure that <tt>x.compareTo(y)==0</tt>
	 * implies that <tt>sgn(x.compareTo(z)) == sgn(y.compareTo(z))</tt>, for all <tt>z</tt>. It is strongly recommended,
	 * but <i>not</i> strictly required that <tt>(x.compareTo(y)==0) == (x.equals(y))</tt>.  Generally speaking, any
	 * class that implements the <tt>Comparable</tt> interface and violates this condition should clearly indicate this
	 * fact.  The recommended language is "Note: this class has a natural ordering that is inconsistent with equals." In
	 * the foregoing description, the notation <tt>sgn(</tt><i>expression</i><tt>)</tt> designates the mathematical
	 * <i>signum</i> function, which is defined to return one of <tt>-1</tt>, <tt>0</tt>, or <tt>1</tt> according to
	 * whether the value of <i>expression</i> is negative, zero or positive.
	 *
	 * @param o the object to be compared.
	 *
	 * @return a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the
	 * 				 specified object.
	 */
	public int compareTo(Object o) {
		if((o != null) && o instanceof GrantedAuthority) {
			Role otherRole = null;

			try {
				otherRole = Role.valueOf(((GrantedAuthority)o).getAuthority());
			} finally {
				// Do nothing
			}

			if(otherRole == null) {
				return -1;
			}

			return role.compareTo(otherRole);
		}

		return -1;
	}
}
